package com.ai.wxy.spring.jpa.user.service;

import com.ai.spring.common.annotation.AddGroup;
import com.ai.spring.common.annotation.EditGroup;
import com.ai.spring.common.enums.DataStatusEnum;
import com.ai.spring.common.enums.ExceptionEnum;
import com.ai.spring.common.exception.ServiceException;
import com.ai.wxy.spring.jpa.user.convert.RoleDTOConvert;
import com.ai.wxy.spring.jpa.user.convert.UserDTOConvert;
import com.ai.wxy.spring.jpa.user.dao.RoleDao;
import com.ai.wxy.spring.jpa.user.dao.UserDao;
import com.ai.wxy.spring.jpa.user.dao.UserRoleDao;
import com.ai.wxy.spring.jpa.user.dto.RoleDTO;
import com.ai.wxy.spring.jpa.user.dto.UserDTO;
import com.ai.wxy.spring.jpa.user.dto.UserRoleDTO;
import com.ai.wxy.spring.jpa.user.entity.Role;
import com.ai.wxy.spring.jpa.user.entity.User;
import com.ai.wxy.spring.jpa.user.entity.UserRole;
import com.ai.wxy.spring.service.api.dto.DefaultServiceParam;
import com.ai.wxy.spring.service.api.dto.DefaultServiceResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户角色
 *
 * @author 石头
 * @Date 2019/11/20
 * @Version 1.0
 **/
@Service
public class UserRoleService implements IUserRoleService {
    @Autowired
    private UserDao userDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private UserRoleDao userRoleDao;
    @Autowired
    private UserDTOConvert convert;
    @Autowired
    private RoleDTOConvert roleConvert;
    /**
     * 添加新用户
     * @param userDTO
     * @return
     */
    public DefaultServiceResult<Long> addUser(@Validated(value = AddGroup.class) UserDTO userDTO){
        User newUser = convert.toEntity(userDTO);
        newUser = userDao.save(newUser);
        return DefaultServiceResult.build(newUser.getId());
    }

    /**
     * 更新用户
     * @param userDTO
     * @return
     */
    public DefaultServiceResult<UserDTO> updUser(@Validated(value = EditGroup.class) UserDTO userDTO){
        User updUser = convert.toEntity(userDTO);
        updUser = userDao.updateBySenstive(updUser);
        return DefaultServiceResult.build(convert.toDto(updUser));
    }

    /**
     * 删除用户
     * @param userId
     * @return
     */
    public DefaultServiceResult<Boolean> delUser(DefaultServiceParam<Long> userId){
        if (userId == null || userId.getParam() == null){
            throw new ServiceException(ExceptionEnum.PARAM_ID_EXIST,"用户");
        }
        Boolean result = userDao.removeById(userId.getParam());
        return DefaultServiceResult.build(result);
    }

    /**
     * 添加角色
     * @param roleDTO
     * @return
     */
    public DefaultServiceResult<Long> addRole(@Validated(value = AddGroup.class)RoleDTO roleDTO){
        Role newRole = roleConvert.toEntity(roleDTO);
        newRole = roleDao.save(newRole);
        return DefaultServiceResult.build(newRole.getId());
    }
    /**
     * 更新角色
     * @param roleDTO
     * @return
     */
    public DefaultServiceResult<RoleDTO> updRole(@Validated(value = EditGroup.class)RoleDTO roleDTO){
        Role updRole = roleConvert.toEntity(roleDTO);
        updRole = roleDao.updateBySenstive(updRole);
        return DefaultServiceResult.build(roleConvert.toDto(updRole));
    }
    /**
     * 删除角色
     * @param roleId
     * @return
     */
    public DefaultServiceResult<Boolean> delRole(DefaultServiceParam<Long> roleId){
        if (roleId == null || roleId.getParam() == null){
            throw new ServiceException(ExceptionEnum.PARAM_ID_EXIST,"角色");
        }
        Boolean result = roleDao.removeById(roleId.getParam());
        return DefaultServiceResult.build(result);
    }

    /**
     * 添加用户角色信息
     * @param userRoleDTO
     * @return
     */
    public DefaultServiceResult<Boolean> addUserRoles(@Validated(value = AddGroup.class)UserRoleDTO userRoleDTO){
        User user = userDao.findById(userRoleDTO.getUserId());
        if (user == null){
            throw new ServiceException(ExceptionEnum.DATA_NO_EXIST,"用户:"+userRoleDTO.getUserId());
        }
        List<RoleDTO> roles = userRoleDTO.getRoles();
        List<Role> addRoles = roleDao.batchSave(roleConvert.toEntity(roles));

        List<UserRole> userRoles = addRoles.stream().map(role -> {
            UserRole userRole = new UserRole();
            userRole.setUserId(user.getId());
            userRole.setRoleId(role.getId());
            return userRole;
        }).collect(Collectors.toList());

        List<UserRole> addUserRoles = userRoleDao.batchSave(userRoles);
        return DefaultServiceResult.build(addUserRoles.size()>0);
    }
    /**
     * 更新用户角色信息
     * @param userRoleDTO
     * @return
     */
    public DefaultServiceResult<Boolean> updUserRoles(@Validated(value = EditGroup.class)UserRoleDTO userRoleDTO){
        User user = userDao.findById(userRoleDTO.getUserId());
        if (user == null){
            throw new ServiceException(ExceptionEnum.DATA_NO_EXIST,"用户:"+userRoleDTO.getUserId());
        }
        List<RoleDTO> roles = userRoleDTO.getRoles();
        List<Long> roleIds  = roles.stream().map(RoleDTO::getRoleId).distinct().collect(Collectors.toList());

        UserRole queryUserRole = new UserRole();
        queryUserRole.setUserId(user.getId());
        queryUserRole.setStatus(DataStatusEnum.VALID.getCode());
        List<UserRole> userRoles = userRoleDao.findBySenstive(queryUserRole);
        List<Long> oldRoleIds = userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(roles)){
            // 删除用户角色
            List<Long> userRoleIds = userRoles.stream().map(UserRole::getId).distinct().collect(Collectors.toList());
            userRoleDao.removeByIds(userRoleIds);
        }else{
            // 更新用户角色
            // 添加，数据库没有,但是入参中有的则需要添加
            List<UserRole> addData = roles.stream().filter(role -> !oldRoleIds.contains(role.getRoleId())).map( role -> {
                UserRole userRole = new UserRole();
                userRole.setUserId(user.getId());
                userRole.setRoleId(role.getRoleId());
                return userRole;
            }).collect(Collectors.toList());
            // 删除，数据库中有的，但是入参中没有
            List<Long> delData = userRoles.stream().filter(role -> !roleIds.contains(role.getRoleId())).map(role -> role.getId()).collect(Collectors.toList());

            userRoleDao.removeByIds(delData);
            userRoleDao.batchSave(addData);
        }

        return DefaultServiceResult.build(Boolean.TRUE);
    }
}
